home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWPart / Sources / FWEdCmd.cpp < prev    next >
Encoding:
Text File  |  1995-11-08  |  13.3 KB  |  474 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWEdCmd.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWEDCMD_H
  13. #include "FWEdCmd.h"
  14. #endif
  15.  
  16. // ----- Framework Includes -----
  17.  
  18. #ifndef FWPART_H
  19. #include "FWPart.h"
  20. #endif
  21.  
  22. #ifndef FWFRAME_H
  23. #include "FWFrame.h"
  24. #endif
  25.  
  26. #ifndef FWSELECT_H
  27. #include "FWSelect.h"
  28. #endif
  29.  
  30. #ifndef FWLNKMGR_H
  31. #include "FWLnkMgr.h"
  32. #endif
  33.  
  34. // ----- OS Layer -----
  35.  
  36. #ifndef FWBARRAY_H
  37. #include "FWBArray.h"
  38. #endif
  39.  
  40. // ----- OpenDoc Includes -----
  41.  
  42. #ifndef SOM_Module_OpenDoc_Commands_defined
  43. #include <CmdDefs.xh>
  44. #endif
  45.  
  46. #ifndef SOM_ODSession_xh
  47. #include <ODSessn.xh>
  48. #endif
  49.  
  50. #ifndef SOM_ODClipboard_xh
  51. #include <Clipbd.xh>
  52. #endif
  53.  
  54. #ifndef SOM_Module_OpenDoc_StdProps_defined
  55. #include <StdProps.xh>
  56. #endif
  57.  
  58. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  59. #include <StdTypes.xh>
  60. #endif
  61.  
  62. #ifndef SOM_ODStorageUnit_xh
  63. #include <StorageU.xh>
  64. #endif
  65.  
  66. #ifndef SOM_ODLinkSpec_xh
  67. #include <LinkSpec.xh>
  68. #endif
  69.  
  70. //========================================================================================
  71. //    Runtime Info
  72. //========================================================================================
  73.  
  74. #if FW_LIB_EXPORT_PRAGMAS
  75. #pragma lib_export on
  76. #endif
  77.  
  78. #ifdef FW_BUILD_MAC
  79. #pragma segment FWFrameworkCommands
  80. #endif
  81.  
  82. FW_DEFINE_CLASS_M1(FW_CEditCommand, FW_CCommand)
  83.  
  84. //====================================================================
  85. // FW_CEditCommand class
  86. //====================================================================
  87.  
  88. //--------------------------------------------------------------------
  89. // FW_CEditCommand constructor
  90. //--------------------------------------------------------------------
  91.  
  92. FW_CEditCommand::FW_CEditCommand(Environment* ev,
  93.                                  ODCommandID id,
  94.                                  FW_CFrame* frame, 
  95.                                  FW_Boolean canUndo) :
  96.     FW_CCommand(ev, id, frame, canUndo),
  97.     fUpdateID(kODUnknownUpdate),
  98.     fCloneKind(kODCloneCopy)
  99. {
  100.     switch (id)
  101.     {
  102.         case kODCommandCopy:
  103.             fCanUndo = FALSE;            // Copy is never Undo-able
  104.             fCausesChange = FALSE;        // Copy doesn't change the data
  105.             break;
  106.         case kODCommandCut:
  107.             fCloneKind = kODCloneCut;
  108.             break;
  109.         case kODCommandPaste:
  110.         case kODCommandPasteAs:
  111.             fCloneKind = kODClonePaste;
  112.             break;
  113.     }
  114. }
  115.  
  116. //--------------------------------------------------------------------
  117. // FW_CEditCommand destructor
  118. //--------------------------------------------------------------------
  119.  
  120. FW_CEditCommand::~FW_CEditCommand()
  121. {
  122. }
  123.  
  124. //--------------------------------------------------------------------
  125. // FW_CEditCommand::DoIt
  126. //--------------------------------------------------------------------
  127.  
  128. void FW_CEditCommand::DoIt(Environment* ev)    // Override
  129. {
  130.     FW_Boolean result = FALSE;
  131.  
  132.     if (fCanUndo)
  133.         this->SaveUndoState(ev);    // save current state, for later Undo
  134.  
  135.     switch (fCommandID)
  136.     {
  137.         case kODCommandCopy:
  138.             this->HandleCopy(ev);
  139.             break;
  140.  
  141.         case kODCommandClear:
  142.             if (this->IsOKtoEdit(ev) && this->HandleClear(ev))
  143.             {
  144.                 this->SetMenuStrings(ev, "Undo Clear", "Redo Clear");
  145.                 result = TRUE;
  146.             }
  147.             break;
  148.  
  149.         case kODCommandCut:
  150.             if (this->IsOKtoEdit(ev) && this->HandleCut(ev))
  151.             {
  152.                 this->SetMenuStrings(ev, "Undo Cut", "Redo Cut");
  153.                 result = TRUE;
  154.             }
  155.             break;
  156.  
  157.         case kODCommandPaste:
  158.             if (this->IsOKtoEdit(ev) && this->HandlePaste(ev))
  159.             {
  160.                 this->SetMenuStrings(ev, "Undo Paste", "Redo Paste");
  161.                 result = TRUE;
  162.             }
  163.             break;
  164.  
  165.         case kODCommandPasteAs:
  166.             if (this->IsOKtoEdit(ev) && this->HandlePasteAs(ev))
  167.             {
  168.                 this->SetMenuStrings(ev, "Undo Paste As", "Redo Paste As");
  169.                 result = TRUE;
  170.             }
  171.             break;
  172.     }
  173.  
  174.     if (result == FALSE)
  175.         fCanUndo = FALSE;
  176.     else if (fCanUndo)
  177.     {
  178.         this->SaveRedoState(ev);        // save new state, for later Redo
  179.     }
  180. }
  181.  
  182.  
  183. //----------------------------------------------------------------------------------------
  184. //    FW_CEditCommand::DoCut
  185. //----------------------------------------------------------------------------------------
  186.  
  187. void FW_CEditCommand::DoCut(Environment* ev)
  188. {
  189.     // User may override; only gets called if the Cut was successful
  190. }
  191.  
  192. //----------------------------------------------------------------------------------------
  193. //    FW_CEditCommand::DoClear
  194. //----------------------------------------------------------------------------------------
  195.  
  196. void FW_CEditCommand::DoClear(Environment* ev)
  197. {
  198.     // User may override; only gets called if the Clear was successful
  199. }
  200.  
  201. //----------------------------------------------------------------------------------------
  202. //    FW_CEditCommand::DoPaste
  203. //----------------------------------------------------------------------------------------
  204.  
  205. void FW_CEditCommand::DoPaste(Environment* ev)
  206. {
  207.     // User may override; only gets called if the Paste was successful
  208. }
  209.  
  210. //----------------------------------------------------------------------------------------
  211. //    FW_CEditCommand::DoPasteAs
  212. //----------------------------------------------------------------------------------------
  213.  
  214. void FW_CEditCommand::DoPasteAs(Environment* ev)
  215. {
  216.     // User may override; only gets called if the Paste As was successful
  217. }
  218.  
  219. //----------------------------------------------------------------------------------------
  220. //    FW_CEditCommand::HandleCut
  221. //----------------------------------------------------------------------------------------
  222.  
  223. FW_Boolean FW_CEditCommand::HandleCut(Environment* ev)
  224. {
  225.     FW_Boolean result = FALSE;
  226.     
  227.     this->Copy(ev, FALSE);    // don't write a link spec for a cut
  228.     result = fSelection->ClearSelection(ev);
  229.  
  230.     if (result)    
  231.     {
  232.         // Give the command subclass a chance to do something
  233.         this->DoCut(ev);
  234.     }
  235.  
  236.     return result;
  237. }
  238.  
  239. //----------------------------------------------------------------------------------------
  240. //    FW_CEditCommand::HandleCopy
  241. //----------------------------------------------------------------------------------------
  242.  
  243. void FW_CEditCommand::HandleCopy(Environment* ev)
  244. {
  245.     FW_Boolean allowPublish = (fSelection && fSelection->IsSelectionPublishable(ev));
  246.     this->Copy(ev, allowPublish);
  247. }
  248.  
  249. //----------------------------------------------------------------------------------------
  250. //    FW_CEditCommand::HandleClear
  251. //----------------------------------------------------------------------------------------
  252.  
  253. FW_Boolean FW_CEditCommand::HandleClear(Environment* ev)
  254. {
  255.     FW_Boolean result = fSelection->ClearSelection(ev);
  256.     if (result)
  257.         this->DoClear(ev);    // Give the command subclass a chance to do something
  258.  
  259.     return result;
  260. }
  261.  
  262. //----------------------------------------------------------------------------------------
  263. //    FW_CEditCommand::Copy
  264. //----------------------------------------------------------------------------------------
  265.  
  266. void FW_CEditCommand::Copy(Environment* ev, FW_Boolean allowLinking)
  267. {
  268.     //---- We have to invalidate any currently pending publisher ----
  269.     FW_CLinkManager* linkMgr = fPart->GetLinkManager(ev);
  270.     if (linkMgr)
  271.         linkMgr->DeletePendingPublish(ev);
  272.  
  273.     //---- Clear all properties and values from the clipboard ----
  274.     ODClipboard* clipboard = fPart->GetSession(ev)->GetClipboard(ev);
  275.     clipboard->Clear(ev);
  276.     ODStorageUnit* clipboardSU = clipboard->GetContentStorageUnit(ev);
  277.     
  278.     //---- Write new data to the clipboard ----
  279.     fSelection->ExternalizeData(ev, fFrame, FW_kClipboardStorage, clipboardSU, fCloneKind);
  280.  
  281.     //---- notify OpenDoc clipboard ----
  282.     fUpdateID = clipboard->ActionDone(ev, fCloneKind);
  283.             
  284.     // ----- Write out Link Spec if possible -----
  285.     if (allowLinking)
  286.     {
  287.         ODLinkSpec* linkSpec = NULL;
  288.         FW_VOLATILE(linkSpec);
  289.         ODUpdateID updateID = clipboard->GetUpdateID(ev);
  290.         FW_CByteArray data(&updateID, sizeof(updateID));
  291.  
  292.         FW_TRY
  293.         {
  294.             linkSpec = fPart->GetStorageUnit(ev)->GetDraft(ev)->CreateLinkSpec(ev, fPart->GetODPart(ev), data);
  295.  
  296.             clipboardSU->AddProperty(ev, kODPropLinkSpec);
  297.             linkSpec->WriteLinkSpec(ev, clipboardSU);
  298.         }
  299.         FW_CATCH_BEGIN
  300.         FW_CATCH_EVERYTHING()
  301.         {
  302.             if (linkSpec)
  303.                 delete linkSpec;
  304.             FW_THROW_SAME();
  305.         }
  306.         FW_CATCH_END
  307.  
  308.         delete linkSpec;
  309.  
  310.         // If current selection is already published, just re-use its publisher
  311.         FW_CPublishLink* publishLink = fSelection->DoFindPublisher(ev);
  312.         if (publishLink)
  313.             publishLink->SetPendingID(ev, updateID);
  314.         else
  315.             publishLink = linkMgr->NewPublishLink(ev, updateID, fFrame->GetPresentation(ev));
  316.         linkMgr->SetPendingPublish(ev, publishLink);
  317.     }
  318. }
  319.  
  320. //----------------------------------------------------------------------------------------
  321. //    FW_CEditCommand::HandlePaste
  322. //----------------------------------------------------------------------------------------
  323.  
  324. FW_Boolean FW_CEditCommand::HandlePaste(Environment* ev)
  325. {
  326.     FW_Boolean result = FALSE;
  327.     
  328.     ODClipboard* clipboard = fPart->GetSession(ev)->GetClipboard(ev);
  329.     ODStorageUnit* clipBSU = clipboard->GetContentStorageUnit(ev);
  330.     
  331.     result = fSelection->InternalizeData(ev, fFrame, clipBSU, fCloneKind) != FW_kInternalizeFailed;
  332.  
  333.     if (result)    
  334.     {
  335.         // notify OpenDoc clipboard
  336.         fUpdateID = clipboard->ActionDone(ev, fCloneKind);
  337.  
  338.         // Give the command subclass a chance to do something
  339.         this->DoPaste(ev);
  340.     }
  341.  
  342.     return result;
  343. }
  344.  
  345. //----------------------------------------------------------------------------------------
  346. //    FW_CEditCommand::HandlePasteAs
  347. //----------------------------------------------------------------------------------------
  348.  
  349. FW_Boolean FW_CEditCommand::HandlePasteAs(Environment* ev)
  350. {
  351.     FW_Boolean result = FALSE;
  352.     FW_Boolean handledIt = FALSE;
  353.     ODPasteAsResult pasteAsResult;
  354.  
  355.     result = this->HandlePasteAsDialog(ev, pasteAsResult, handledIt);
  356.     if (!handledIt)
  357.     {
  358.         if ((pasteAsResult.translateKind != kODNULL))    // user wants data translated
  359.             result = this->DoPasteTranslation(ev, pasteAsResult);
  360.         else
  361.         {
  362.             fCommandID = kODCommandPaste;
  363.             result = this->HandlePaste(ev);        // no translation, just an ordinary paste
  364.         }
  365.     }
  366.     else if (result)
  367.     {
  368.         // Give the command subclass a chance to do something
  369.         this->DoPasteAs(ev);
  370.     }
  371.  
  372.     return result;
  373. }
  374.  
  375. //----------------------------------------------------------------------------------------
  376. //    FW_CEditCommand::HandlePasteAsDialog
  377. //----------------------------------------------------------------------------------------
  378. FW_Boolean FW_CEditCommand::HandlePasteAsDialog(Environment* ev, ODPasteAsResult& pasteAsResult, 
  379.                                                 FW_Boolean& handledIt)
  380. {
  381.     FW_Boolean result = FALSE;
  382.     ODPasteAsMergeSetting mergeSetting;
  383.     ODBoolean canPasteLink = FALSE;
  384.     FW_CLinkManager* linkMgr = fPart->GetLinkManager(ev);
  385.  
  386.     ODClipboard* clipboard = fPart->GetSession(ev)->GetClipboard(ev);
  387.     ODStorageUnit* clipboardSU = clipboard->GetContentStorageUnit(ev);
  388.  
  389.     // ---- Check whether the selection supports linking ----
  390.     if (linkMgr && fSelection->CanSubscribe(ev, mergeSetting))
  391.     {
  392. /*        if (clipboardSU->Exists(ev, kODPropLinkSpec, (ODValueType)NULL, 0))    [MEB] OpenDoc calls this */
  393.             canPasteLink = TRUE;
  394.     }
  395.  
  396.     // ---- Display the Paste As... dialog ----
  397.     result = clipboard->ShowPasteAsDialog(ev, canPasteLink, mergeSetting, 
  398.                                           fFrame->GetActiveFacet(ev),    // facet from which dialog is triggered
  399.                                           fFrame->GetViewType(ev),        // viewType of data
  400.                                           &pasteAsResult);
  401.  
  402.     if (result == kODFalse)
  403.         handledIt = TRUE;                // we tried, but the user cancelled
  404.     else
  405.     {
  406.         // --- Figure out what to do depending on settings from Paste As dialog
  407.         if (pasteAsResult.pasteLinkSetting == kODTrue)        // user wants to create a Link
  408.         {
  409.             result = linkMgr->PasteWithLink(ev, clipboardSU, pasteAsResult, fFrame->GetPresentation(ev));
  410.             handledIt = TRUE;
  411.         }
  412.         else if (pasteAsResult.mergeSetting == kODFalse)    // user wants to embed a Part w/o Linking
  413.         {
  414.             result = this->DoPasteAsEmbed(ev, clipboardSU);
  415.             handledIt = TRUE;
  416.         }
  417.         else    // Merge with Contents - let Paste command handle that
  418.         {
  419.             handledIt = FALSE;
  420.         }
  421.     }
  422.  
  423.     return result;
  424. }
  425.  
  426. //----------------------------------------------------------------------------------------
  427. //    FW_CEditCommand::DoPasteTranslation
  428. //----------------------------------------------------------------------------------------
  429. FW_Boolean FW_CEditCommand::DoPasteTranslation(Environment* ev, ODPasteAsResult& pasteAsResult)
  430. {
  431.     // Override to translate the data and paste it.
  432.     // Use the clipboard content SU.
  433.  
  434.     return FALSE;
  435. }
  436.  
  437. //----------------------------------------------------------------------------------------
  438. //    FW_CEditCommand::DoPasteAsEmbed
  439. //----------------------------------------------------------------------------------------
  440. FW_Boolean FW_CEditCommand::DoPasteAsEmbed(Environment* ev, ODStorageUnit* storageUnit)
  441. {
  442.     FW_UNUSED(storageUnit);
  443.  
  444.     // Override to paste the contents of the storageUnit as an embedded part (no linking)
  445.     return FALSE;
  446. }
  447.  
  448. //----------------------------------------------------------------------------------------
  449. //    FW_CEditCommand::UndoIt
  450. //----------------------------------------------------------------------------------------
  451.  
  452. void FW_CEditCommand::UndoIt(Environment* ev)    // Override
  453. {
  454.     if ((fCommandID == kODCommandCut) || (fCommandID == kODCommandPaste))
  455.     {
  456.         ODClipboard* clipboard = fPart->GetSession(ev)->GetClipboard(ev);
  457.         clipboard->ActionUndone(ev, fUpdateID, fCloneKind);
  458.     }
  459. }
  460.  
  461. //----------------------------------------------------------------------------------------
  462. //    FW_CEditCommand::RedoIt
  463. //----------------------------------------------------------------------------------------
  464.  
  465. void FW_CEditCommand::RedoIt(Environment* ev)    // Override
  466. {
  467.     if ((fCommandID == kODCommandCut) || (fCommandID == kODCommandPaste))
  468.     {
  469.         ODClipboard* clipboard = fPart->GetSession(ev)->GetClipboard(ev);
  470.         clipboard->ActionRedone(ev, fUpdateID, fCloneKind);
  471.     }
  472. }
  473.  
  474.